package com.multi.tenant.service.impl;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.multi.common.core.domain.AjaxResult;
import com.multi.common.core.domain.entity.SysUser;
import com.multi.common.exception.BkTenantException;
import com.multi.common.utils.DateUtils;
import com.multi.common.utils.SecurityUtils;
import com.multi.common.utils.http.HttpUtils;
import com.multi.common.utils.sign.Base64;
import com.multi.source.service.SystemDbService;
import com.multi.source.util.DataBaseUtils;
import com.multi.system.mapper.SysUserMapper;
import com.multi.system.service.ISysUserService;
import com.multi.tenant.domain.BkTenantSignupInfo;
import com.multi.tenant.resp.LabelResp;
import com.multi.tenant.service.IBkTenantSignupInfoService;
import com.multi.tenant.util.HttpServiceUtils;
import com.multi.tenant.util.TokenUtils;
import com.multi.tenant.vo.BkTenantInfoVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.multi.tenant.mapper.BkTenantInfoMapper;
import com.multi.common.core.domain.entity.BkTenantInfo;
import com.multi.tenant.service.IBkTenantInfoService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;

/**
 * 后台租户Service业务层处理
 *
 * @author pzj
 * @date 2024-11-11
 */
@Service
public class BkTenantInfoServiceImpl implements IBkTenantInfoService {
    @Autowired
    private BkTenantInfoMapper bkTenantInfoMapper;

    @Autowired
    private IBkTenantSignupInfoService bkTenantSigupInfoService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private HttpServiceUtils httpServiceUtils;

    @Autowired
    private TokenUtils tokenUtils;

    private final String url = "http://127.0.0.1:8000/system/user";


    /**
     * 查询后台租户
     *
     * @param id 后台租户主键
     * @return 后台租户
     */
    @Override
    public BkTenantInfo selectBkTenantInfoById(Long id) {
        return bkTenantInfoMapper.selectBkTenantInfoById(id);
    }

    /**
     * 查询后台租户列表
     *
     * @param bkTenantInfo 后台租户
     * @return 后台租户
     */
    @Override
    public List<BkTenantInfo> selectBkTenantInfoList(BkTenantInfo bkTenantInfo) {
        return bkTenantInfoMapper.selectBkTenantInfoList(bkTenantInfo);
    }

    /**
     * 新增租户后，输入租户入住年限，生成签约管理信息，生成租户用户信息
     *
     * @param bkTenantInfoVo 后台租户
     * @return 结果
     */
    @Override
    public Boolean insertBkTenantInfo(BkTenantInfoVo bkTenantInfoVo, HttpServletRequest request) {
        //1、创建租户信息  2、创建签约信息   3、创建对应租户关联表  4、创建租户用户
        Boolean execute = transactionTemplate.execute(e -> {
            BkTenantInfo bkTenantInfo = new BkTenantInfo();
            BeanUtils.copyProperties(bkTenantInfoVo, bkTenantInfo);
            //1、创建租户信息
            bkTenantInfo.setCreateTime(DateUtils.getNowDate());
            bkTenantInfo.setCreateBy(SecurityUtils.getUsername());
            //对AppID和AppSecret进行加密
            bkTenantInfo.setTenantAppid(Base64.encode(bkTenantInfo.getTenantAppid().getBytes()));
            bkTenantInfo.setTenantAppsecret(Base64.encode(bkTenantInfo.getTenantAppsecret().getBytes()));
            bkTenantInfoMapper.insertBkTenantInfo(bkTenantInfo);
            //2、创建签约信息
            Integer tenantTime = bkTenantInfoVo.getTenantTime();//单位年
            LocalDate now = LocalDate.now();
            LocalDate localDate = now.plusYears(tenantTime);//计算签约到期时间
            BkTenantSignupInfo bkTenantSigupInfo = new BkTenantSignupInfo()
                    .setTenantId(bkTenantInfo.getId())
                    .setTenantSignupCount(1L)
                    .setTenantSignupDate(now)
                    .setTenantDeadline(localDate);
            bkTenantSigupInfoService.insertBkTenantSignupInfo(bkTenantSigupInfo);
            //3、TODO 设置租户关联表
            //4、为当前租户创建管理员用户
            SysUser sysUser = new SysUser();
            sysUser.setUserName(bkTenantInfo.getTenantLeader());
            sysUser.setAvatar(bkTenantInfo.getTenantAvatar());
            sysUser.setPassword(bkTenantInfo.getTenantTel());
            sysUser.setPhonenumber(bkTenantInfo.getTenantTel());
            sysUser.setRoleId(2L);
            sysUser.setNickName(bkTenantInfo.getTenantLeader());
            //设置请求头
            String token = tokenUtils.getToken(request);
            AjaxResult ajaxResult = httpServiceUtils.doPost(url, token, sysUser);
            if (ajaxResult.isSuccess()) {
                return Boolean.TRUE;
            } else {
                return Boolean.FALSE;
            }
        });
        return execute;
    }

    /**
     * 修改后台租户
     *
     * @param bkTenantInfoVo 后台租户
     * @return 结果
     */
    @Override
    public Boolean updateBkTenantInfo(BkTenantInfoVo bkTenantInfoVo) {
        Boolean execute = transactionTemplate.execute(e -> {
            //修改租户信息
            BkTenantInfo bkTenantInfo = new BkTenantInfo();
            BeanUtils.copyProperties(bkTenantInfoVo,bkTenantInfo);
            //进行AppID和AppSecret信息加密
            bkTenantInfo.setTenantAppid(Base64.encode(bkTenantInfo.getTenantAppid().getBytes()));
            bkTenantInfo.setTenantAppsecret(Base64.encode(bkTenantInfo.getTenantAppsecret().getBytes()));
            bkTenantInfo.setUpdateTime(DateUtils.getNowDate());
            bkTenantInfo.setUpdateBy(SecurityUtils.getUsername());
            bkTenantInfoMapper.updateBkTenantInfo(bkTenantInfo);
            return Boolean.TRUE;
        });
        if(!execute){
            throw new BkTenantException("修改租户失败");
        }
        return execute;
    }

    /**
     * 批量删除后台租户
     *
     * @param ids 需要删除的后台租户主键
     * @return 结果
     */
    @Override
    @Transactional
    public Boolean deleteBkTenantInfoByIds(Long[] ids) {
        //先查询各个租户下是否含有用户在使用
        List<SysUser> sysUsers = sysUserService.selectByTenantIds(ids);
        Integer idCount = ids.length;
        Map<Long, List<SysUser>> userMap = sysUsers.stream().collect(Collectors.groupingBy(SysUser::getTenantId));
        for (Long tenantId : ids) {
            List<SysUser> userList = userMap.get(tenantId);
            if (CollectionUtils.isEmpty(userList)) {
                idCount -= bkTenantInfoMapper.deleteBkTenantInfoById(tenantId);
            }
        }
        if (idCount == 0) {
            return Boolean.TRUE;
        } else {
            return Boolean.FALSE;
        }
    }

    /**
     * 删除后台租户信息
     *
     * @param id 后台租户主键
     * @return 结果
     */
    @Override
    public int deleteBkTenantInfoById(Long id) {
        return bkTenantInfoMapper.deleteBkTenantInfoById(id);
    }

    /**
     * 获取租户键值信息
     *
     * @param bkTenantInfo
     * @return
     */
    @Override
    public List<LabelResp> selectTenantTreeList(BkTenantInfo bkTenantInfo) {
        List<BkTenantInfo> bkTenantInfos = bkTenantInfoMapper.selectBkTenantInfoList(bkTenantInfo);
        List<LabelResp> labelResps = new ArrayList<>();
        for (BkTenantInfo tenantInfo : bkTenantInfos) {
            LabelResp labelResp = new LabelResp();
            labelResp.setLabel(tenantInfo.getTenantName())
                    .setValue(tenantInfo.getId());
            labelResps.add(labelResp);
        }
        return labelResps;
    }


}
